home *** CD-ROM | disk | FTP | other *** search
/ PC Media 7 / PC MEDIA CD07.iso / share / prog / cm / cmordarr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-06  |  6.6 KB  |  277 lines

  1. // CmOrdArr.cpp
  2. // -----------------------------------------------------------------
  3. // Compendium - C++ Container Class Library
  4. // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
  5. // -----------------------------------------------------------------
  6. // Ordered array implementation.
  7. // -----------------------------------------------------------------
  8.  
  9. #include <cm/include/cmordarr.h>
  10.  
  11.  
  12. // "CmOrderedArray" is the default array constructor.
  13. //
  14. CmOrderedArray::CmOrderedArray(unsigned sz, unsigned dt)
  15. {
  16.   _delta   = dt;
  17.   _total   = 0;
  18.   _entries = (sz > 0) ? new CmObject*[sz] : NULL;
  19.   _size    = (_entries != NULL) ? sz : 0;
  20. }
  21.  
  22.  
  23. // "CmOrderedArray" is the array copy constructor.
  24. //
  25. CmOrderedArray::CmOrderedArray(const CmOrderedArray& A)
  26. {
  27.   _delta   = A._delta;
  28.   _total   = 0;
  29.   _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
  30.   _size    = (_entries != NULL) ? A._size : 0;
  31.   copy(A);
  32. }
  33.  
  34.  
  35. // "~CmOrderedArray" is the array destructor.
  36. //
  37. CmOrderedArray::~CmOrderedArray()
  38. {
  39.   removeAll();
  40.   delete[] _entries;
  41. }
  42.  
  43.  
  44. // "=" assignement operator copies the contents of the specified
  45. // array into this array.
  46. //
  47. CmOrderedArray& CmOrderedArray::operator=(const CmOrderedArray& A)
  48. {
  49.   if (&A != this)
  50.   {
  51.     removeAll();
  52.     delete[] _entries;
  53.     _delta   = A._delta;
  54.     _total   = 0;
  55.     _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
  56.     _size    = (_entries != NULL) ? A._size : 0;
  57.     copy(A);
  58.   }
  59.   return *this;
  60. }
  61.  
  62.  
  63. // "add" appends the specified object to the array.
  64. //
  65. Bool CmOrderedArray::add(CmObject* pObj)
  66. {
  67.   if (!pObj) return FALSE;
  68.  
  69.   if (_total >= _size)
  70.     if (_delta == 0 || !resize(_size+_delta))
  71.       return FALSE;
  72.  
  73.   int idx = shouldGo(pObj);
  74.   if (idx == -1) return FALSE;
  75.  
  76.   if (idx != _total)
  77.   {
  78.     size_t sz = (_total - idx) * sizeof(CmObject*);
  79.     memmove(&(_entries[idx+1]), &(_entries[idx]), sz);
  80.   }
  81.  
  82.   _entries[idx] = pObj;
  83.   _total++;
  84.   return TRUE;
  85. }
  86.  
  87.  
  88. // "remove" removes the first occurrence of an object that isEqual to
  89. // the specified object from the array.
  90. //
  91. Bool CmOrderedArray::remove(CmObject* pObj)
  92. {
  93.   if (_total == 0 || !pObj) return FALSE;
  94.   int  ii    = 0;
  95.   Bool found = FALSE;
  96.   while (ii < _total && !found)
  97.     if (_entries[ii++]->isEqual(pObj)) found = TRUE;
  98.   return (found) ? removeAt(ii-1) : FALSE;
  99. }
  100.  
  101.  
  102. // "removeAt" removes the object at the specified index.
  103. //
  104. Bool CmOrderedArray::removeAt(int idx)
  105. {
  106.   if (idx < 0 || idx >= _total) return FALSE;
  107.  
  108.   if (ownsObjects()) delete _entries[idx];
  109.   size_t sz = (_total - idx + 1) * sizeof(CmObject*);
  110.   memmove(&(_entries[idx]), &(_entries[idx+1]), sz);
  111.   _entries[_total-1] = NULL;
  112.   _total--;
  113.   return TRUE;
  114. }
  115.  
  116.  
  117. // "index" returns the index of the first occurrence of an object
  118. // that isEqual to the specified object.
  119. //
  120. int CmOrderedArray::index(CmObject* pObj) const
  121. {
  122.   if (_total == 0 || !pObj) return FALSE;
  123.   int  ii  = 0;
  124.   int  idx = -1;
  125.   while (ii < _total && idx == -1)
  126.     if (_entries[ii++]->isEqual(pObj)) idx = ii-1;
  127.   return idx;
  128. }
  129.  
  130.  
  131. // "shouldGo" reports the index where the specified object would be
  132. // inserted if it were added to the array.
  133. //
  134. int CmOrderedArray::shouldGo(CmObject* pObj) const
  135. {
  136.   if (!pObj || _total == _size) return -1;
  137.  
  138.   if (_total == 0) return 0;
  139.   if (pObj->compare(_entries[_total-1]) >= 0) return _total;
  140.  
  141.   int idx = -1;
  142.   int ii  = 0;
  143.   while (ii < _total && idx == -1)
  144.   {
  145.     if (pObj->compare(_entries[ii]) < 0) idx = ii;
  146.     else                                 ii++;
  147.   }
  148.  
  149.   return idx;
  150. }
  151.  
  152.  
  153. // "lookup" returns the first occurrence of an object that isEqual
  154. // to the specified object.
  155. //
  156. CmObject* CmOrderedArray::lookup(CmObject* pObj) const
  157. {
  158.   int idx = index(pObj);
  159.   return (idx > -1) ? _entries[idx] : NULL;
  160. }
  161.  
  162.  
  163. // "occurrences" returns the number of objects in the array
  164. // isEqual to the specified object.
  165. //
  166. unsigned CmOrderedArray::occurrences(CmObject* pObj) const
  167. {
  168.   if (_total == 0 || !pObj) return 0;
  169.  
  170.   int      ii  = 0;
  171.   unsigned num = 0;
  172.   while (ii < _total)
  173.     if (_entries[ii++]->isEqual(pObj)) num++;
  174.   return num;
  175. }
  176.  
  177.  
  178. // "removeAll" removes all objects from the array.
  179. //
  180. void CmOrderedArray::removeAll()
  181. {
  182.   for (int ii = 0; ii < _total; ii++)
  183.   {
  184.     if (ownsObjects()) delete _entries[ii];
  185.     _entries[ii] = NULL;
  186.   }
  187.   _total = 0;
  188. }
  189.  
  190.  
  191. // "resize" resizes the storage allocated for this array.
  192. //
  193. Bool CmOrderedArray::resize(unsigned newSize)
  194. {
  195.   if (newSize == 0)
  196.   {
  197.     removeAll();
  198.     delete[] _entries;
  199.     _entries = NULL;
  200.     _size    = 0;
  201.     return TRUE;
  202.   }
  203.  
  204.   CmObject **newEntries = new CmObject*[newSize];
  205.   if (!newEntries) return FALSE;
  206.  
  207.   if (newSize < _total)
  208.   {
  209.     for (int ii = newSize; ii < _total; ii++)
  210.       if (ownsObjects()) delete _entries[ii];
  211.     _total = newSize;
  212.   }
  213.  
  214.   memmove(newEntries, _entries, _total * sizeof(CmObject*));
  215.  
  216.   delete[] _entries;
  217.   _entries = newEntries;
  218.   _size    = newSize;
  219.   return TRUE;
  220. }
  221.  
  222.  
  223. // "isEmpty" checks if the array is empty or not.
  224. //
  225. Bool CmOrderedArray::isEmpty() const
  226. {
  227.   return (_total == 0);
  228. }
  229.  
  230.  
  231. // "newIterator" creates and returns an array iterator.
  232. //
  233. CmIterator* CmOrderedArray::newIterator() const
  234. {
  235.   return new CmOrderedArrayIterator(*this);
  236. }
  237.  
  238.  
  239. // "write" writes the array objects to the specified reserve file.
  240. //
  241. Bool CmOrderedArray::write(CmReserveFile& file) const
  242. {
  243.   if (!writeBase(file))    return FALSE;          // Write base container.
  244.   if (!file.write(_delta)) return FALSE;          // Write delta value.
  245.   if (!file.write(_total)) return FALSE;          // Write number of objects.
  246.  
  247.   Bool success = TRUE;
  248.   int  ii      = 0;
  249.   while (ii < _total && success)                  // For each object.
  250.     success = _entries[ii++]->writeObject(file);  // Write the object.
  251.   return success;
  252. }
  253.  
  254.  
  255. // "read" reads the array objects from the specified reserve file.
  256. //
  257. Bool CmOrderedArray::read(CmReserveFile& file)
  258. {
  259.   unsigned size = readBase(file);                 // Read base container.
  260.  
  261.   unsigned total;
  262.   if (!file.read(_delta)) return FALSE;           // Read delta value.
  263.   if (!file.read(total))  return FALSE;           // Read number of objects.
  264.   if (!resize(size))      return FALSE;           // Resize the array.
  265.  
  266.   removeAll();
  267.  
  268.   Bool success = TRUE;
  269.   int  ii      = 0;
  270.   while (ii < total && success)                   // For each object,
  271.   {
  272.     CmObject *pObj = CmObject::readObject(file);  // Read object.
  273.     if (pObj) success = add(pObj); ii++;          // Add to array.
  274.   }
  275.   return success;
  276. }
  277.